/**
 * <p>版权所有：中企动力
 * <p>未经本公司许可，不得以任何方式复制或使用本程序任何部分
 */
package com.ce.pms.house.service.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ce.pms.exception.BusinessException;
import com.ce.pms.base.service.impl.PmsBaseServiceImpl;
import com.ce.pms.charge.dao.ICharStoChoMeterDao;
import com.ce.pms.charge.dao.IMeterDataRegisterDao;
import com.ce.pms.charge.model.CharStaChoDomain;
import com.ce.pms.charge.model.ChargeDatasDomain;
import com.ce.pms.charge.service.IMeterDataRegisterService;
import com.ce.pms.charge.vo.OriginalMeterDataVO;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.customer.dao.IProRightDao;
import com.ce.pms.customer.model.ProRightDO;
import com.ce.pms.house.dao.IBuildingDao;
import com.ce.pms.house.dao.IChargeDatasDao;
import com.ce.pms.house.dao.IHouseDao;
import com.ce.pms.house.dao.IMeterDao;
import com.ce.pms.house.model.HouseDomain;
import com.ce.pms.house.model.MeterDomain;
import com.ce.pms.house.model.MeterType;
import com.ce.pms.house.service.IHouseService;
import com.ce.pms.house.service.IMeterService;
import com.ce.pms.house.service.IProRightChangeService;
import com.ce.pms.house.vo.MeterVO;
import com.ce.util.BeanUtil;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.support.Page;

/**
 * 功能描述: MeterServiceImpl
 *
 * @author  付湘辉
 * Created on：  2008-7-8
 * @author  付湘辉
 * update on：  2008-7-8
 */

public class MeterServiceImpl extends PmsBaseServiceImpl implements
		IMeterService {

	/**
	 * 方法描述: 根据走表ID查询MeterVO
	 * @author 胡煦
	 * Create on:2008-10-21
	 * @param nameStr：查询条件班级名称
	 * @return 返回当前页的查询结果
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public MeterVO findMeterVOBy(Long meterId){

		MeterDomain meterDomain = meterDao.findById(meterId);
		MeterVO meterVO = this.assembleD2V(meterDomain);
		ChargeDatasDomain meterData = meterDataRegisterDao.getMeterDatasListByHouseIdAndMeterId(meterVO.getHouseId(), meterId);
		meterVO.setLastNumer(meterData==null?meterVO.getBase(): meterData.getThisReading());
		String owner = houseService.getOwnerNameBy(meterVO.getHouseNumber());
		meterVO.setOwnersStr(owner);
		return this.setMeterVOForList(meterVO, meterData);
	}

	/**
	 * 方法描述: 为List页面显示根据走表ID查询MeterVO
	 * @author 胡煦
	 * Create on:2008-10-21
	 * @param meterId
	 * @return MeterVO
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	private MeterVO setMeterVOForList(MeterVO meterVO,ChargeDatasDomain meterData){
		//ChargeDatasDomain meterData = meterDataRegisterDao.getMeterDatasListByHouseIdAndMeterId(meterVO.getHouseId(), meterId);
		if(SysrefcodeDO.CONSTANTS_DIGITAL_ZERO.equals(meterVO.getValidity())){
			//ChargeDatasDomain newMeterData = meterDataRegisterDao.getMeterDatasListByHouseIdAndMeterId(meterVO.getHouseId(), meterVO.getKeyword());
			meterVO.setLastNumer(meterData==null?meterVO.getBase(): meterData.getLastReading());
			meterVO.setChangesNumer(meterData==null?null: meterData.getThisReading());
			meterVO.setCurrentDosage(meterData==null?null: meterData.getWastage());
		}else{
			meterVO.setLastNumer(meterData==null?null: meterData.getThisReading());
		}

		return meterVO;
	}

	/**
	 *
	 * 功能描述: 添加走表信息
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param meterVo
	 * @return MeterVO 返回结果
	 */
	public MeterVO addMeter(MeterVO meterVo) throws BusinessException{

		meterVo.setValidity(SysrefcodeDO.CONSTANTS_DIGITAL_ONE);//设为有效
		MeterDomain meterDomain = this.assembleV2D(meterVo);
		try {
			this.meterDao.saveObject(meterDomain);
		} catch (Exception e) {
			throw new BusinessException("house:meter_save_failure_exception",BusinessException.WARNING);
		}

		//得到id
		meterVo.setKeyword(meterDomain.getKeyword());

		return meterVo;
	}

	/**
	 *
	 * 功能描述: 根据房屋id获得走表资料分页信息
	 *
	 * @author 胡煦
	 * Created on:2008-7-17
	 *
	 * 修改原因：
	 * @param meterVo
	 * @return Page 返回结果
	 */
	public Page queryPageMeterListByHouseId(Long houseId,Integer pageNo,Integer pageSize) {
		super.checkParameterIsNull("common:parameters_null_exception, ", houseId,pageNo,pageSize);

		Page page = meterDao.queryPageMeterByHouseId(houseId,pageNo,pageSize);
		List<MeterDomain> meterDomainList = page.getResult();
		List<MeterVO> meterVOList = null;
		if (!BlankUtil.isBlank(meterDomainList)) {
			meterVOList = new ArrayList<MeterVO>();
			MeterVO tempMeterVo = null;
			for (MeterDomain domain : meterDomainList) {
				tempMeterVo = this.findMeterVOBy(domain.getKeyword());
				meterVOList.add(tempMeterVo);
			}
		}
		page.setResult(meterVOList);
		return page;
	}


	/**
	 *
	 * 功能描述: 删除走表
	 *
	 * @author 胡煦
	 * Created on:2008-7-17
	 *
	 * 修改原因：
	 * @param meterId
	 * @return void
	 */
	public void deleteMeter(Long meterId) throws BusinessException{
		super
		.checkParameterIsNull(meterId,
				"common:parameters_null_exception, ");
		try {
			this.meterDao.deleteObjectById(meterId);
		} catch (Exception e) {
			throw new BusinessException("house:001",BusinessException.WARNING);
		}
	}
	/**
	 *
	 * 功能描述: 批量添加同一类走表信息
	 *　(此方法需要优化处理)
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param meterVo
	 * @return Boolean 成功:true  失败:false
	 */
	public Boolean addMeterBatch(MeterVO meterVo) throws BusinessException{
		super.checkParameterIsNull(meterVo, "common:parameters_null_exception, ");
		String buildingString = meterVo.getBuildingIdStr();
		if (BlankUtil.isBlank(buildingString)) {
			return false;
		}

		List<Long> list = new ArrayList<Long>();
		String[] buildingIdStrArray = buildingString.split(SysInfo.SEPARATOR_COMMA);
		//遍历所有要添加走表的楼栋
		for (int i = 0; i < buildingIdStrArray.length; i++) {
			//得到楼栋下的房屋列表,其中已过滤在走表数据表中已存在的房屋
			List<Long> tempList = this.houseDao.getHouseIdListByBuildingId(Long.valueOf(buildingIdStrArray[i]), meterVo.getMeterTypeId());
			if (!BlankUtil.isBlank(tempList)) {
				list.addAll(tempList);
			}
		}

		SysInfo sysInfo = super.createInfo(meterVo.getCreator());
		String meterName = meterVo.getMeterTypeName()
				+ SysrefcodeDO.CONSTANTS_DIGITAL_ZERO
				+ SysrefcodeDO.CONSTANTS_DIGITAL_ONE;

		List<Object[]> paramList = new ArrayList<Object[]>();
		for (Long houseId : list) {
			Object[] temp = new Object[5];
			temp[0]=meterName;//走表名称
			temp[1]=meterVo.getMeterTypeId();//走表类型id
			temp[2]=houseId;//房屋id
			temp[3]=sysInfo.getCreator();//创建人id
			temp[4]=sysInfo.getSysDate();//创建日期
			paramList.add(temp);
		}
		Boolean res = true;
		if (SysrefcodeDO.CONSTANTS_ZERO < list.size()) {
			res = this.meterDao.addMeterBatch(paramList);
		}

		return res;
	}

	/**
	 *
	 * 功能描述: 修改走表底数
	 *
	 * @author 胡煦
	 * Created on:2008-7-17
	 *
	 * 修改原因：
	 * @param meterVo
	 * @return MeterVO 返回结果
	 */
	public MeterVO editMeterRadix(MeterVO meterVO) {
		super
		.checkParameterIsNull(meterVO,
				"common:parameters_null_exception, ");
		MeterDomain meterDomain = meterDao.findById(meterVO.getKeyword());

		if(meterVO.getBase().doubleValue() < 0){
			throw new BusinessException("house:meter_number_error_exception");
		}
		meterDomain.setBase(meterVO.getBase());

		SysInfo sysInfo = meterDomain.getSysInfo();

		modifyInfo(sysInfo, meterVO.getModifier());

		return meterVO;

	}
	/**
	 * 方法描述: 检查某房间下该类型是否存在有效的表,返回true说明有，false则没有
	 * @author 胡煦
	 * Create on:2008-8-21
	 * @param houseId,meterTypecode
	 * @return boolean
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public boolean checkMeterBy(Long houseId,String meterTypecode){
		return meterDao.getMeterByHouseId(houseId, meterTypecode)!=null ;
	}
	/**
	 * 方法描述:根据房间ID和类型CODE查询有效的走表
	 * @author 胡煦
	 * Create on:2008-8-21
	 * @param houseId,meterTypecode
	 * @return MeterVO
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public MeterVO getMeterByType(Long houseId,String meterTypecode){
		MeterDomain meterDomain = meterDao.getMeterByHouseId(houseId, meterTypecode);
		return this.assembleD2V(meterDomain) ;
	}
	/**
	 * 方法描述: 验证该房间是否处于退伙中和是否拥有产权
	 * @author 胡煦
	 * Create on:2008-12-3
	 * @param houseId
	 * @return void
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public void checkTheHouseIsInGoout(Long houseId){

		ProRightDO proRightDO = proRightDao.getEffectiveProRightByHouseId(houseId);
		 if(BlankUtil.isBlank(proRightDO)){
			 throw new BusinessException("house:meter_proright_not_exist_exception",
						BusinessException.WARNING);
		 }
		String str = proRightChangeService.checkTheHouseNumber(houseId);
		if(!BlankUtil.isBlank(str)){
			throw new BusinessException("house:meter_house_ingoout_exception", BusinessException.WARNING);
		}

	}

	/**
	 *
	 * 功能描述: 更换走表
	 *
	 * @author 胡煦
	 * Created on:2008-7-17
	 *
	 * 修改原因：
	 * @param meterVo
	 * @return MeterVO 返回结果
	 */
	public MeterVO changeMeter(MeterVO meterVO)throws BusinessException {
		super
		.checkParameterIsNull(meterVO,
				"common:parameters_null_exception, ");
		//验证该房间是否处于退伙中
		this.checkTheHouseIsInGoout(meterVO.getHouseId());
		//原来的表
		MeterDomain oldMeter = meterDao.findById(meterVO.getOldKeyword());
		//新增原始数据
		OriginalMeterDataVO meterDataVO = new OriginalMeterDataVO();
		meterDataVO.setCreator(meterVO.getCreator());
		meterDataVO.setHouseId(meterVO.getHouseId());
		meterDataVO.setRecordTime(this.getDate());
		meterDataVO.setLastReading(meterVO.getLastNumer());
		meterDataVO.setMeterId(oldMeter.getKeyword());
		meterDataVO.setMeterType(oldMeter.getMeterType().getCode());
		meterDataVO.setOwners(meterVO.getOwnersStr());
		meterDataVO.setThisReading(meterVO.getChangesNumer());
		meterDataRegisterService.addOriginalMeterData(meterDataVO);
		//作废原来的表
		oldMeter.setValidity(SysrefcodeDO.CONSTANTS_DIGITAL_ZERO);
		SysInfo sysInfo = oldMeter.getSysInfo();
		modifyInfo(sysInfo, meterVO.getCreator());
		//新增表
		MeterVO newMeter = this.addMeter(meterVO);
		//新增收费标准选用
		List<CharStaChoDomain> charStaChoDoList = charStoChoMeterDao.queryCharStaChoDoBy(meterVO.getHouseId(), meterVO.getOldKeyword());
		if(!BlankUtil.isBlank(charStaChoDoList)){
			for(CharStaChoDomain charStaChoDomain : charStaChoDoList){
				CharStaChoDomain newChoDomain = new CharStaChoDomain();
				newChoDomain.setHouse(charStaChoDomain.getHouse());
				newChoDomain.setChargeItem(charStaChoDomain.getChargeItem());
				newChoDomain.setChargeSta(charStaChoDomain.getChargeSta());
				newChoDomain.setMeter(meterDao.findById(newMeter.getKeyword()));
				newChoDomain.setStartTime(charStaChoDomain.getStartTime());
				newChoDomain.setEndTime(charStaChoDomain.getEndTime());
				newChoDomain.setSysInfo(createInfo(meterVO.getCreator()));
				charStoChoMeterDao.saveObject(newChoDomain);
			}
		}
		return newMeter;
	}
//	/**
//	 *
//	 * 功能描述: 根据ID得到MeterVO
//	 *
//	 * @author 胡煦
//	 * Created on:2008-7-17
//	 *
//	 * 修改原因：
//	 * @param meterId
//	 * @return MeterVO 返回结果
//	 */
//	public MeterVO getMeterById(Long meterId) {
//		MeterDomain meterDomain = meterDao.findById(meterId);
//		MeterVO meterVO = assembleD2V(meterDomain);
//		return meterVO;
//	}

	/* (non-Javadoc)
	 * @see com.ce.pms.house.service.IMeterService#getMeterList(java.lang.Long)
	 */
	/**
	 * 方法描述: 根据房间ID查询所有有效的走表
	 * @author 胡煦
	 * Create on:2009-1-16
	 * @param houseId
	 * @return List<MeterVO>
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public List<MeterVO> getMeterListByhouseId(Long houseId) {
		List<MeterDomain> meterDoList = meterDao.getMeterListByHouseId(houseId);
		List<MeterVO> meterVoList = null;
		if(!BlankUtil.isBlank(meterDoList)){
			meterVoList = new ArrayList<MeterVO>();
			for(MeterDomain meterDomain : meterDoList){
				meterVoList.add(this.assembleD2V(meterDomain));
			}
		}
		return meterVoList;
	}

	/**
	 *
	 * 功能描述: 查询走表类型列表
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @return List<MeterType> 返回结果
	 */
	public List<MeterType> getMeterTypeList(){
		return this.meterDao.getMeterTypeList();
	}

	/**
	 * 功能描述: 得到一个新的走表名称 <br>
	 * meterVo 中必须包含三个属性值，houseId：房屋id,meterTypeId：走表类型id,meterTypeName：走表类型名称<br>
	 * @param meterVo
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-23  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public String getNewMeterName(MeterVO meterVo){
		super.checkParameterIsNull(meterVo, "common:parameters_null_exception, ");
		return this.generationMeterName(meterVo.getHouseId(),
									    meterVo.getMeterTypeId(),
									    meterVo.getMeterTypeName());
	}

	/**
	 * 功能描述: 设置meterDao
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param meterDao the meterDao to set
	 */
	public void setMeterDao(IMeterDao meterDao) {
		this.meterDao = meterDao;
	}

	/**
	 * 功能描述: 设置houseDao
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param houseDao the houseDao to set
	 */
	public void setHouseDao(IHouseDao houseDao) {
		this.houseDao = houseDao;
	}

	/**
	 * 功能描述: 设置buildingDao
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param buildingDao the buildingDao to set
	 */
	public void setBuildingDao(IBuildingDao buildingDao) {
		this.buildingDao = buildingDao;
	}

	/**
	 * 功能描述: 将一个走表ＶＯ对象装配成一个走表DO实体对象
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 * @param MeterVO
	 * @return MeterDomain 返回结果
	 */
	private MeterDomain assembleV2D(MeterVO meterVo) {
		MeterDomain meterDomain= new MeterDomain();

//		PopulateUtil.populate(meterVo, meterDomain, null, null);
		BeanUtil.convertVoAsDo(meterVo, meterDomain);
		MeterType meterType = this.meterDao.getMeterTypeById(meterVo.getMeterTypeId());//走表类型
		if (!BlankUtil.isBlank(meterType)) {
			meterDomain.setMeterType(meterType);
			//生成一个新的名字
//			meterVo.setName(this.generationMeterName(meterVo.getHouseId(),meterType.getKeyword(),meterType.getName()));
//			meterDomain.setName(meterVo.getName());
		}

		HouseDomain house = this.houseDao.findById(meterVo.getHouseId());//房屋
		if (!BlankUtil.isBlank(house)) {
			meterDomain.setHouse(house);
		}
		if(BlankUtil.isBlank(meterVo.getBase())){
			meterDomain.setBase(new BigDecimal(0.00));
		}

		SysInfo sysInfo = super.createInfo(meterVo.getCreator());
		meterDomain.setSysInfo(sysInfo);//创建信息

		return meterDomain;
	}

	/**
	 * 功能描述:  将一个走表DO实体对象装配成一个走表ＶＯ对象 <br>
	 * @param meterDomain
	 * @return MeterVO
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-17  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private MeterVO assembleD2V(MeterDomain meterDomain) {
		MeterVO meterVo = new MeterVO();

		BeanUtil.convertVoAsDo(meterDomain, meterVo);

		MeterType meterType = meterDomain.getMeterType();//走表类型
		if (!BlankUtil.isBlank(meterType)) {
			meterVo.setMeterTypeId(meterType.getKeyword());
			meterVo.setMeterTypeCode(meterType.getCode());
			meterVo.setMeterTypeName(meterType.getName());
			meterVo.setMAXZ(new BigDecimal(setMap().get(meterType.getCode()).toString()));
		}

		HouseDomain house = meterDomain.getHouse();//房屋
		if (!BlankUtil.isBlank(house)) {
			meterVo.setHouseId(house.getKeyword());
			meterVo.setHouseNumber(house.getHouseNumber());
		}

		SysInfo sysInfo = meterDomain.getSysInfo();//创建信息
		if (!BlankUtil.isBlank(sysInfo)) {
			meterVo.setCreator(sysInfo.getCreator());
			meterVo.setSysDate(sysInfo.getSysDate());
		}


		return meterVo;
	}

	private Map setMap(){
		Map meterMaxMap = new HashMap();
		BigInteger waterMaxz = meterDao.getMAXZByMeterTypeCode("001");
		BigInteger ammerMaxz = meterDao.getMAXZByMeterTypeCode("002");
		BigInteger oilMaxz = meterDao.getMAXZByMeterTypeCode("003");
		meterMaxMap.put("001", waterMaxz);
		meterMaxMap.put("002", ammerMaxz);
		meterMaxMap.put("003", oilMaxz);
		return meterMaxMap;
	}

	/**
	 * 功能描述: 生成一个走表新名称，规则：水表01　水表02 <br>
	 * @param meterVo
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-22  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private String generationMeterName(Long houseId,Long meterTypeId,String name){
		super.checkParameterIsNull("common:parameters_null_exception, ", houseId,meterTypeId,name);

		Long count = this.meterDao.getMeterCountBy(houseId, meterTypeId);
		count += 1;
		String nameSuffix = count<10?"0"+String.valueOf(count):String.valueOf(count);
		String newName = name+nameSuffix;

		return newName;
	}

	/**
	 * 走表Dao
	 */
	private IMeterDao meterDao;
	/**
	 * 走表原始数据Dao
	 */
	private IChargeDatasDao chargeDatasDao;

	private IMeterDataRegisterService meterDataRegisterService;

	private IMeterDataRegisterDao meterDataRegisterDao;

	private ICharStoChoMeterDao charStoChoMeterDao;

	private IHouseService houseService;

	private IProRightChangeService proRightChangeService;

	private IProRightDao proRightDao;

	/**
	 * 房屋Dao
	 */
	private IHouseDao houseDao;

	/**
	 * 楼栋Dao
	 */
	private IBuildingDao buildingDao;


	public MeterVO calculateDosage(MeterVO meterVO) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @param chargeDatasDao the chargeDatasDao to set
	 */
	public void setChargeDatasDao(IChargeDatasDao chargeDatasDao) {
		this.chargeDatasDao = chargeDatasDao;
	}

	/**
	 * @param meterDataRegisterService the meterDataRegisterService to set
	 */
	public void setMeterDataRegisterService(
			IMeterDataRegisterService meterDataRegisterService) {
		this.meterDataRegisterService = meterDataRegisterService;
	}

	/**
	 * @param charStoChoMeterDao the charStoChoMeterDao to set
	 */
	public void setCharStoChoMeterDao(ICharStoChoMeterDao charStoChoMeterDao) {
		this.charStoChoMeterDao = charStoChoMeterDao;
	}

	/**
	 * @param meterDataRegisterDao the meterDataRegisterDao to set
	 */
	public void setMeterDataRegisterDao(IMeterDataRegisterDao meterDataRegisterDao) {
		this.meterDataRegisterDao = meterDataRegisterDao;
	}

	/**
	 * @param houseService the houseService to set
	 */
	public void setHouseService(IHouseService houseService) {
		this.houseService = houseService;
	}

	/**
	 * @param proRightChangeService the proRightChangeService to set
	 */
	public void setProRightChangeService(
			IProRightChangeService proRightChangeService) {
		this.proRightChangeService = proRightChangeService;
	}

	/**
	 * @param proRightDao the proRightDao to set
	 */
	public void setProRightDao(IProRightDao proRightDao) {
		this.proRightDao = proRightDao;
	}

}
